/*****************************************************************************
Copyright 2006 Kervin L. Pierre
    EMAIL: otlkcon@adevsoft.com

This file is part of Otlkcon.

Otlkcon is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

Otlkcon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Lesser GNU General Public License for more details.

You should have received a copy of the Lesser GNU General Public License
along with Otlkcon; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*******************************************************************************/

#include "stdafx.h"
#include "ochelper.h"

extern int otlkcon_debugLevel;
extern int otlkcon_logToFileEnabled;
extern wchar_t otlkcon_logFile[MAX_PATH+1];

int LOG_PRINTF(int level, int flag, wchar_t *format, ...)
{

    // Honour debug level...
    if( !(otlkcon_debugLevel & level) )
        return 0;

    int result = S_OK;

    FILE *stream;
    va_list argList;

    size_t pos;
    wchar_t logTime[10] = {0};
    wchar_t  msg[OTLKCON_LOG_MSG_MAX_LEN] = {0};

    if( flag == OTLKCON_LOG_TARGET_NONE )
        return 0;

    /* Format message, plus time into message buffer */
    if( flag & OTLKCON_LOG_FLAG_NO_DATE )
    {
        pos = 0;
    }
    else
    {
        _wstrtime_s(logTime);
        pos = wcslen(logTime) + 10;
        swprintf_s(msg, OTLKCON_LOG_MSG_MAX_LEN, 
            L"0x%0.4x [%s] ", GetCurrentThreadId(), logTime);
    }

    va_start(argList, format);
    result = _vsnwprintf_s( &msg[pos], OTLKCON_LOG_MSG_MAX_LEN-(pos+1),
                        OTLKCON_LOG_MSG_MAX_LEN-(pos+2), format, argList);
    va_end(argList);


    if( otlkcon_logToFileEnabled == 1  
        && ( flag & OTLKCON_LOG_TARGET_FILE 
                || flag & OTLKCON_LOG_TARGET_ALL ) )
    {
        /* TODO: logfile I/O should be protected by a mutex */
        errno_t errRes = 0;
        if( wcslen(otlkcon_logFile) == 0 )
            errRes = _wfopen_s( &stream, OTLKCON_LOG_DEFAULT_FILE, L"a+");
        else errRes = _wfopen_s( &stream, otlkcon_logFile, L"a+");

        if( errRes == 0 )
        {
            /* file is unbuffered */
            setvbuf(stream, NULL, _IONBF, 0);

            fwprintf_s(stream, L"%s", msg);
            fclose(stream); 
        }
    }

    wprintf_s( L"%s", msg);

#ifdef OTLKCON_LOG_MSVC_DEBUGGER_ENABLED
    if( otlkcon_logToMSVCEnabled == 1 
        && ( flag & OTLKCON_LOG_TARGET_MSVC 
                || flag & OTLKCON_LOG_TARGET_ALL ) )
    {
        OutputDebugStringW(msg);
    }
#endif /* OTLKCON_LOG_MSVC_DEBUGGER_ENABLED */
/*
#ifdef OTLKCON_LOG_SM_SUPPORT_ENABLED
    if( otlkcon_logToSMEnabled == 1 )
    {
        if( flag & OTLKCON_LOG_TARGET_SM  )
        {
            smlog_write(otlkcon_processSMServerContext, msg);
        }
        else if( flag & OTLKCON_LOG_TARGET_ALL )
        {
    #ifdef OTLKCON_LOG_IMPLICIT_PRINTF_TO_SM
            smlog_write(otlkcon_processSMServerContext, msg);
    #endif // OTLKCON_LOG_IMPLICIT_PRINTF_TO_SM 
        }
    }
#endif  // OTLKCON_LOG_SM_SUPPORT_ENABLED 
*/
    /* Warn about truncation */
    if( (wcslen(msg) >= OTLKCON_LOG_MSG_MAX_LEN-1)
        && (_scwprintf(L"WARNING: The above message may have been truncated\r\n%d == LOG_MSG_MAX, %d.",
            wcslen(msg), OTLKCON_LOG_MSG_MAX_LEN) < OTLKCON_LOG_MSG_MAX_LEN-1) )
    {
        LOG_PRINTF(OTLKCON_LOG_LEVEL_WARNING, NULL, 
            L"WARNING: The above message may have been truncated\r\n%d == LOG_MSG_MAX, %d.",
            wcslen(msg), OTLKCON_LOG_MSG_MAX_LEN);
    }

    return result;
}